home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / zc / main.c < prev    next >
C/C++ Source or Header  |  1989-03-08  |  10KB  |  539 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    main.c
  12.  *
  13.  *    Main routine, error handling, keyword lookup.
  14.  *
  15.  *
  16.  *   Revised: Dec 1988    Joe Montgomery
  17.  *
  18.  *   Revised main.c to use Amiga File System Naming Conventions
  19.  *    Added ?,C,F switches. ? help
  20.  *                  C force data,bss into Chip memory
  21.  *                  F force data,bss into Fast memory
  22.  *    To be added -o switch to specify assembly output
  23.  *
  24.  *     other modules:
  25.  *   Revised out.c to use MOTOROLA assembly directives in order
  26.  *    to be compatible with C.Gibbs a68k assembler & blink
  27.  *    Added END statement
  28.  *    Changed .comm label,size to label DC.x 0
  29.  *   Revised d2.c so that externs are declared as XREF -----
  30.  *   Revised g2.c & gen.c to declare all called functions XREF
  31.  *     (will need to change this to declare only external functions)
  32.  *
  33.  *
  34.  *   All changes labeled JMM
  35.  */
  36.  
  37. #include <stdio.h>
  38. #include "param.h"
  39. #include "nodes.h"
  40. #include "tok.h"
  41.  
  42. extern short usechipmemory,usefastmemory;
  43. int lineno;
  44. int nmerrors;
  45. int oflags[26];
  46. int xflags[26];
  47. int pflag = 0;            /* enable profiling */
  48. static int anydebug;
  49. #define debug oflags['z'-'a']
  50.  
  51.  
  52. FILE *input;
  53. FILE *output;
  54. #if CC68
  55. FILE *fopenb();
  56. #define fopen fopenb
  57. #endif
  58. char *inname;
  59.  
  60. #if NEEDBUF
  61. char my_ibuf[BUFSIZ];
  62. #endif
  63.  
  64. NODEP cur;
  65.  
  66. /* JMM changed defines to be compatible with AMIGA */
  67. static    char *defines[] = {
  68.     "MC68000",
  69.     "mc68000",
  70.     "SOZOBON",
  71.     "MCH_AMIGA",
  72.     "AmigaDOS",
  73.     NULL
  74. };
  75.  
  76. static    char    Version[] =
  77. "zc: Amiga Version 1.01  Copyright (c) 1988 by Sozobon, Limited.\n";
  78.  
  79. static char Version2[] =
  80. "    modified by J.Montgomery. Now generates Motorola compatible \n";
  81. static char Version3[] =
  82. "   assembly code.\n";
  83. extern char *outfilename,*errorfile;
  84.  
  85.  
  86. main(argc, argv)
  87. char **argv;
  88. {
  89.     char    *p, *getenv();
  90.     int shownames;
  91.     int i;
  92.  
  93. /* JMM added switches to force data,bss into chip or fast memory */
  94.     usefastmemory = 0;
  95.     usechipmemory = 0;  /* don't force data into either chip or fast*/
  96.     outfilename = (char *) NULL;
  97.  
  98. /* JMM force hcc to always print out version */
  99.     printf(Version);
  100.     if (sizeof(NODE) & 3) {
  101.         printf("sizeof NODE not mult of 4\n");
  102.         exit(1);
  103.     }
  104.  
  105.     /*
  106.      * Define the "built-in" macros
  107.      */
  108.     for (i=0; defines[i] != NULL; i++)
  109.         optdef(defines[i]);
  110.  
  111.     /*
  112.      * Parse the INCLUDE environment variable, if present.
  113.      */
  114.     if ((p = getenv("INCLUDE")) != NULL){
  115.         if( doincl(p) == 1 )exit(0);
  116.     }
  117.     shownames = 0;
  118.     if (isatty(0)) {
  119.         write(1, "\33v", 2);
  120.         setbuf(stdout, NULL);
  121.     }
  122. /* put author here */
  123.     while (argc-- > 1) {
  124.         argv++;
  125.         if(argv[0][0] == '?') {
  126.             doopt(&argv[0][0]);
  127.             exit(1);
  128.         }
  129.         if(argv[0][0] == '-')
  130.               doopt(&argv[0][1]);
  131. #if CC68
  132.         else if (argv[0][0] == '+') {
  133.             upstr(&argv[0][1]);
  134.             doopt(&argv[0][1]);
  135.         }
  136. #endif
  137.         else {
  138.             if (argc > 1 || shownames) {
  139.                 shownames++;
  140.                 printf("%s:\n", argv[0]);
  141.             }
  142.             if (input != NULL)
  143.                 fclose(input);
  144.             input = fopen(argv[0], ROPEN);
  145.             if (input == NULL) {
  146.                 printf("Cant open %s\n", argv[0]);
  147.                 exit(1);
  148.             }
  149. #if NEEDBUF
  150.             setbuf(input, my_ibuf);
  151. #endif
  152.             inname = argv[0];
  153.             dofile();
  154.         }
  155.     }
  156.     if (input == NULL) {
  157.         input = stdin;
  158.         output = stdout;
  159.         inname = "<STDIN>";
  160.         dofile();
  161.     }
  162.     exit(0);
  163. }
  164.  
  165. doincl(s)
  166. char    *s;
  167. {
  168.     char    *malloc(), *strcpy();
  169.     char    buf[256];
  170.     char    dir[128];
  171.     register char    *p;
  172.  
  173.  
  174.     strcpy(buf, s);
  175.     /*
  176.      * Convert ',' and ';' to nulls
  177.      */
  178.     for (p=buf; *p != '\0' ;p++)
  179.         if (*p == ',' || *p == ';')
  180.             *p = '\0';
  181.     p[1] = '\0';                    /* double null terminated */
  182.  
  183.     /*
  184.      * Grab each directory, make sure it ends with a slash,
  185.      * and add it to the directory list.
  186.      */
  187.     for (p=buf; *p != '\0' ;p++) {
  188.         strcpy(dir, p);
  189.       /* JMM use Amiga file naming conventions */
  190.         if (dir[strlen(dir)-1] != '/' && dir[strlen(dir)-1] != ':')
  191.             strcat(dir, "/");
  192.  
  193.         optincl( strcpy(malloc((unsigned) (strlen(dir) + 1)), dir) );
  194.  
  195.         while (*p != '\0')
  196.             p++;
  197.     }
  198. }
  199.  
  200.  
  201. extern int nodesmade, nodesavail;
  202. extern NODEP deflist[], symtab[], tagtab;
  203. extern NODEP strsave;
  204. extern int level;
  205. dofile()
  206. {
  207.     char *scopy();
  208.     int i;
  209.  
  210.     out_start(inname);
  211.     inname = scopy(inname);
  212.     lineno = 1;
  213.     nmerrors = 0;
  214.     advnode();
  215.  
  216.     level = 0;
  217.     program();
  218.     dumpstrs(strsave);
  219.  
  220.     out_end();
  221.     if (cur && cur->e_token == EOFTOK)
  222.         freenode(cur);
  223.     sfree(inname);
  224.     for (i=0; i<NHASH; i++) {
  225.         if (debug>1 && deflist[i]) {
  226.             printf("defines[%d]", i);
  227.             printlist(deflist[i]);
  228.         }
  229.         freenode(deflist[i]);
  230.         deflist[i] = NULL;
  231.         if (debug && symtab[i]) {
  232.             printf("gsyms[%d]", i);
  233.             printlist(symtab[i]);
  234.         }
  235.         freenode(symtab[i]);
  236.         symtab[i] = NULL;
  237.     }
  238.     if (debug) {
  239.         printf("structs");
  240.         printlist(tagtab);
  241.     }
  242.     freenode(tagtab);
  243.     tagtab = NULL;
  244.     freenode(strsave);
  245.     strsave = NULL;
  246.     if (nmerrors) {
  247.         printf("%d errors\n", nmerrors);
  248.         exit(1);
  249.     }
  250.     if (nodesmade != nodesavail) {
  251.         printf("lost %d nodes!!!\n", nodesmade-nodesavail);
  252.         exit(1);
  253.     }
  254. /*
  255.     printf("Space = %ldK\n", ((long)nodesavail*sizeof(NODE))/1024);
  256. */
  257. }
  258.  
  259. dooutfile(s)
  260. char    *s;
  261. {
  262.      char    *malloc(), *strcpy();
  263.  
  264.      outfilename = strcpy(malloc((unsigned)(strlen(s) + 1)), s );
  265. }
  266.  
  267. doerrorfile(s)
  268. char *s;
  269. {
  270.      char  *malloc(),*strcpy();
  271.  
  272.      errorfile = strcpy(malloc((unsigned)(strlen(s) + 1)), s);
  273. }
  274.  
  275. doopt(s)
  276. char *s;
  277. {
  278.     register char c;
  279.  
  280.     while ((c = *s++)) {
  281. #ifdef    DEBUG
  282.         if (c >= 'a' && c <='z') {
  283.             oflags[c-'a']++;
  284.             anydebug++;
  285.         } else
  286. #endif
  287.         if ( (c >= 'A' && c <= 'Z') || c == '?') {
  288.             switch (c) {
  289.             case 'D':
  290.                 optdef(s);
  291.                 return;
  292.             case 'U':
  293.                 optundef(s);
  294.                 return;
  295.             case 'I':
  296.                 doincl(s);
  297.                 return;
  298.             case 'P':
  299.                 pflag = 1;
  300.                 continue;
  301.             case 'V':
  302.                 printf("%s %s",Version2,Version3);
  303.                 continue;
  304. /* JMM added ?,C,F,O,E    switches */
  305.             case 'E': /* specify error file */
  306.                 doerrorfile(s);
  307.                 return(1);
  308.             case 'O':
  309.                 dooutfile(s);
  310.                 return(1);
  311.             case 'C':
  312.                 if(usefastmemory){
  313.                    printf(" Can't use both Chip & Fast memory\n");
  314.                    return(1);
  315.                 }
  316.                 usechipmemory = 1;
  317.                 continue;
  318.              case 'F':
  319.                 if(usechipmemory){
  320.                    printf(" Can't use both Chip & Fast memory\n");
  321.                    return(1);
  322.                 }
  323.                 usefastmemory = 1;
  324.                 continue;
  325.             case '?':
  326.                 printf("%s %s",Version2,Version3);
  327.                 printf("    The Correct Syntax is \n");
  328.                 printf("zc [FLAGS] SOURCEFILE \n");
  329.                 printf("    The valid compiler flags are : \n");
  330.                 printf("\n  -Dxxxx   Define xxxx\n  -Uxxxx   Undefine xxxx\n");
  331.                 printf("  -Ixxxx   Include Directory = xxxx\n  -P   profiler\n");
  332.                 printf("  -Oxxxx   outputfile name = xxxx\n");
  333.                 printf("  -V   display compiler version\n  -?   Help\n");
  334.                 printf("  -C   force Data,Bss into Chip memory \n");
  335.                 printf("  -F   force Data,Bss into Fast memory \n");
  336.                 return(1);
  337.                 continue;
  338.             }
  339. #ifdef    DEBUG
  340.             xflags[c-'A']++;
  341.             anydebug++;
  342. #endif
  343.         }
  344.     }
  345. return(0);
  346. }
  347.  
  348. errors(s,t)
  349. char *s, *t;
  350. {
  351.     optnl();
  352.     printf("error in %s on line %d: %s %s\n", inname, lineno, s,t);
  353.     nmerrors++;
  354. }
  355.  
  356. errorn(s,np)
  357. char *s;
  358. NODE *np;
  359. {
  360.     optnl();
  361.     printf("error in %s on line %d: %s ", inname, lineno, s);
  362.     put_nnm(np);
  363.     putchar('\n');
  364.     nmerrors++;
  365. }
  366.  
  367. error(s)
  368. char *s;
  369. {
  370.     optnl();
  371.     printf("error in %s on line %d: %s\n", inname, lineno, s);
  372.     nmerrors++;
  373. }
  374.  
  375. warns(s,t)
  376. char *s, *t;
  377. {
  378.     optnl();
  379.     printf("warning in %s on line %d: %s %s\n", inname, lineno, s,t);
  380. }
  381.  
  382. warnn(s,np)
  383. char *s;
  384. NODE *np;
  385. {
  386.     optnl();
  387.     printf("warning in %s on line %d: %s ", inname, lineno, s);
  388.     put_nnm(np);
  389.     putchar('\n');
  390. }
  391.  
  392. warn(s)
  393. char *s;
  394. {
  395.     optnl();
  396.     printf("warning in %s on line %d: %s\n", inname, lineno, s);
  397. }
  398.  
  399. fatals(s,t)
  400. char *s, *t;
  401. {
  402.     optnl();
  403.     printf("fatal error in %s on line %d: %s %s\n", inname, lineno, s,t);
  404.     exit(1);
  405. }
  406.  
  407. fataln(s,np)
  408. char *s;
  409. NODE *np;
  410. {
  411.     optnl();
  412.     printf("fatal error in %s on line %d: %s ", inname, lineno, s);
  413.     put_nnm(np);
  414.     putchar('\n');
  415.     exit(1);
  416. }
  417.  
  418. fatal(s)
  419. char *s;
  420. {
  421.     optnl();
  422.     printf("fatal error in %s on line %d: %s\n", inname, lineno, s);
  423.     exit(1);
  424. }
  425.  
  426. static
  427. optnl()
  428. {
  429.     if (anydebug)
  430.         putchar('\n');
  431. }
  432.  
  433. struct kwtbl {
  434.     char *name;
  435.     int    kwval;
  436.     int    kflags;
  437. } kwtab[] = {
  438.     /* must be sorted */
  439.     {"asm", K_ASM},
  440.     {"auto", K_AUTO},
  441.     {"break", K_BREAK},
  442.     {"case", K_CASE},
  443.     {"char", K_CHAR},
  444.     {"continue", K_CONTINUE},
  445.     {"default", K_DEFAULT},
  446.     {"do", K_DO},
  447.     {"double", K_DOUBLE},
  448.     {"else", K_ELSE},
  449.     {"enum", K_ENUM},
  450.     {"extern", K_EXTERN},
  451.     {"float", K_FLOAT},
  452.     {"for", K_FOR},
  453.     {"goto", K_GOTO},
  454.     {"if", K_IF},
  455.     {"int", K_INT},
  456.     {"long", K_LONG},
  457.     {"register", K_REGISTER},
  458.     {"return", K_RETURN},
  459.     {"short", K_SHORT},
  460.     {"sizeof", K_SIZEOF},
  461.     {"static", K_STATIC},
  462.     {"struct", K_STRUCT},
  463.     {"switch", K_SWITCH},
  464.     {"typedef", K_TYPEDEF},
  465.     {"union", K_UNION},
  466.     {"unsigned", K_UNSIGNED},
  467.     {"void", K_VOID},
  468.     {"while", K_WHILE},
  469.  
  470.     {0,0}
  471. };
  472.  
  473. #define FIRST_C 'a'
  474. #define LAST_C    'z'
  475. struct kwtbl *kwstart[LAST_C-FIRST_C+1];
  476.  
  477. kw_init()
  478. {
  479.     register struct kwtbl *p;
  480.     register c;
  481.  
  482.     for (p=kwtab; p->name; p++) {
  483.         c = p->name[0];
  484.         if (kwstart[c-FIRST_C] == 0)
  485.             kwstart[c-FIRST_C] = p;
  486.     }
  487. }
  488.  
  489. kw_tok(tp)
  490. NODE *tp;
  491. {
  492.     register struct kwtbl *kp;
  493.     register char *nm;
  494.     register i;
  495.     static first = 0;
  496.  
  497.     nm = tp->n_name;
  498.     if (first == 0) {
  499.         kw_init();
  500.         first = 1;
  501.     }
  502.     i = nm[0];
  503.     if (i < FIRST_C || i > LAST_C)
  504.         return;
  505.     kp = kwstart[i-FIRST_C];
  506.     if (kp)
  507.     for (; kp->name; kp++) {
  508.         i = strcmp(nm, kp->name);
  509.         if (i == 0) {
  510.             tp->e_token = kp->kwval;
  511.             tp->e_flags = kp->kflags;
  512.             return;
  513.         } else if (i < 0)
  514.             return;
  515.     }
  516. }
  517.  
  518. #if CC68
  519. /* fix args since stupid lib makes all lower case */
  520. upstr(s)
  521. char *s;
  522. {
  523.     while (*s) {
  524.         if (*s >= 'a' && *s <= 'z')
  525.             *s += 'A'-'a';
  526.         s++;
  527.     }
  528. }
  529. downstr(s)
  530. char *s;
  531. {
  532.     while (*s) {
  533.         if (*s >= 'A' && *s <= 'Z')
  534.             *s -= 'A'-'a';
  535.         s++;
  536.     }
  537. }
  538. #endif
  539.